//
//  AliPayUtils.m
//  UtilsDemo
//
//  Created by wulanzhou on 16/10/9.
//  Copyright © 2016年 wulanzhou. All rights reserved.
//

#import "AliPayUtils.h"
#import "Order.h"
#import "RSADataSigner.h"
#import <AlipaySDK/AlipaySDK.h>

/****************************支付宝配置*****************************/

#define ALIXPAY_APPID                     @"2016121204157854"
//私钥不改变
#define ALIXPAY_RSAPRIVATEKEY               @"MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALaIMO0abSYV0YgLZCkh+o0KHhCK9pEon3qHuTuGrJMCvDNIa9c+UHTZgUrUnpnnCtAT3XZkcpIb8nYicTfsyQDzhbHLzsSTJPqOFB9oSyItaezsOWFUkQMcQ6Hkzbv0gLfMIcmTLFfnl6Z7bsxuI9uIwBUMdWSy8mgy1dJD2F/9AgMBAAECgYBtTHHXmGphUtFL4F5SjwkjqTpFd6CbXTLZwSm2rjbqNMoS/zusAKFWxuM3tsddqs57uFl1SkKcoOV3vboD3eKhjjAJNUXrHjGyHCCzmqT+pzDs1W8fnvETpBZxlK9hHFAgOCcfb6s29OwCrdDQzDUMOYZZWcLUgpPviB/t/7/RFQJBAO085EtxnlSiwiQ/x6fBP3Yc/QDFoy0YDksvLvGbprDlIDN0sgkBup6yA7XF6rejd79YKKfKUXWidktP0xvBnLMCQQDE97oFNpYxRhd4mYxyQn9bJXuwYEAWhR5nFhGqMsuixuXemU1ubKq1ifOFRRuib7aIdhEr+MLf118Fl/LNosiPAkBojrG/Xm/9tU4DU+jW0qD5mYUYVgK42SVTlZQHACbTR+iNRR1CQvTRBHwGHRh5nx4jwuMIMG7+fX/NaX0NeqNpAkBfGq47Liw/BnT2yk1CLlGIFQUwGIlZVlVjuQg2gehJZHhBjwwQMXALz9xBkSjSudYM9dU8whR2OGutK70VBXCJAkALotbiiT0/cgC6wAg61AV83AN1hE4Vwgz3j8cPRwB3pbiFw+rVy4BDBDbp/qM8B/uR2l3i3hTHeWJ6i8vZDBIc"

#define ALIXPAY_APPSCHEME                   @"AliPayUtils"   //支付回调的scheme(应用注册scheme,在AlixPayDemo-Info.plist定义URL types)

/****************************************************************/

NSString * const kAliPayCallBackNotification  = @"kAliPayCallBackNotification";

@interface AliPayUtils ()
@property (nonatomic,copy) AliPayFinishedBlock payFinishedBlock;
@end

@implementation AliPayUtils

- (void)dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (id)init{
    if (self=[super init]) {
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveAlixCallBack:) name:kAliPayCallBackNotification object:nil];
    }
    return self;
}


/**
 *  支付(客户端处理签名)
 *
 *  @param title              商品标题
 *  @param desc               商品描述
 *  @param money              支付金额
 *  @param orderidStr         订单编号
 *  @param notifyURL          回调地址
 *  @param aPayFinishedBlock  支付结果回调
 */
- (void)alixPayWithTitle:(NSString*)title
             productDesc:(NSString*)desc
                   money:(NSString *)moneyStr
             orderNumber:(NSString *)orderidStr
               notifyURL:(NSString *)notifyURL
            payCompleted:(AliPayFinishedBlock)aPayFinishedBlock{

    self.payFinishedBlock=aPayFinishedBlock;
    
    /*
     *生成订单信息及签名
     */
    //将商品信息赋予AlixPayOrder的成员变量
    Order* order = [Order new];
    
    // NOTE: app_id设置
    order.app_id = ALIXPAY_APPID;
    
    // NOTE: 支付接口名称
    order.method = @"alipay.trade.app.pay";
    
    // NOTE: 参数编码格式
    order.charset = @"utf-8";
    
    // NOTE: 当前时间点
    NSDateFormatter* formatter = [NSDateFormatter new];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    order.timestamp = [formatter stringFromDate:[NSDate date]];
    
    // NOTE: 支付版本
    order.version = @"1.0";
    
    // NOTE: sign_type 根据商户设置的私钥来决定
    order.sign_type = @"RSA";
    
    // NOTE: 商品数据
    order.biz_content = [BizContent new];
    order.biz_content.body = desc;
    order.biz_content.subject = title;
    order.biz_content.out_trade_no = orderidStr; //订单ID（由商家自行制定）
    order.biz_content.timeout_express = @"30m"; //超时时间设置
    order.biz_content.total_amount = moneyStr; //商品价格
    

    //将商品信息拼接成字符串
    NSString *orderInfo = [order orderInfoEncoded:NO];
    NSString *orderInfoEncoded = [order orderInfoEncoded:YES];
    //NSLog(@"orderSpec = %@",orderSpec);
    
    //获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
    RSADataSigner* signer = [[RSADataSigner alloc] initWithPrivateKey:ALIXPAY_RSAPRIVATEKEY];
    NSString *signedString = [signer signString:orderInfo withRSA2:NO];
    
    //NSLog(@"signedString = %@",signedString);
    
    //将签名成功字符串格式化为订单字符串,请严格按照该格式
    
    if (signedString != nil) {
        // NOTE: 将签名成功字符串格式化为订单字符串,请严格按照该格式
        NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@",
                                 orderInfoEncoded, signedString];
        NSLog(@"orderString = %@",orderString);
        
        //NSLog(@"orderString = %@",orderString);
        
        // NOTE: 调用支付结果开始支付
        [[AlipaySDK defaultService] payOrder:orderString fromScheme:ALIXPAY_APPSCHEME callback:^(NSDictionary *resultDic) {
            //返回结果需要通过 resultStatus 以及 result 字段的值来综合判断并确定支付结果
            //在 resultStatus=9000,并且 success="true"以及 sign="xxx"校验通过的情况下,证 明支付成功
            //其它情况归为失败。较低安全级别的场合,也可以只通过检查 resultStatus 以及 success="true"来判定支付结果
            //1.1 业务错误码  9000 订单支付成功 1.2 8000 正在处理中 1.3 4000 订单支付失败
            //2.1 客户端错误码 9000 订单支付成功 8000 正在处理中 4000 订单支付失败 6001 用户中途取消 6002 网络连接出错
            [self handlerAlixPayFinishedWithUserInfo:resultDic];
        }];
    }else{
        if (self.payFinishedBlock) {
            self.payFinishedBlock(NO,@"-2",@"签名失败");
        }
        self.payFinishedBlock=nil;
    }
}

/**
 *  支付(后台处理签名)
 *
 *  @param sign              签名字符串(后台处理返回的签名)
 *  @param aPayFinishedBlock 支付结果回调
 */
- (void)alixPayWithSign:(NSString *)sign
           payCompleted:(AliPayFinishedBlock)aPayFinishedBlock{
    self.payFinishedBlock=aPayFinishedBlock;
    [[AlipaySDK defaultService] payOrder:sign fromScheme:ALIXPAY_APPSCHEME callback:^(NSDictionary *resultDic) {
        [self handlerAlixPayFinishedWithUserInfo:resultDic];
    }];
}


#pragma mark -私有方法

/**
 *  通知处理
 *
 *  @param notification
 */
- (void)receiveAlixCallBack:(NSNotification*)notification{
    [self handleOpenURL:(NSURL*)[notification object]];
}

/**
 *  支付宝客户端回调处理
 *
 *  @param url
 */
- (void)handleOpenURL:(NSURL *)url {
    [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
        [self handlerAlixPayFinishedWithUserInfo:resultDic];
    }];
}

/**
 *  支付完成处理
 *
 *  @param resultDic
 */
- (void)handlerAlixPayFinishedWithUserInfo:(NSDictionary*)resultDic{
    
    BOOL paySuccess=NO;
    NSString *resultStatus=[resultDic objectForKey:@"resultStatus"];
    NSString *strMemo=[resultDic objectForKey:@"memo"];
    
    if ([resultStatus length]>0) {
        if ([resultStatus isEqual:@"9000"]) {
            paySuccess=YES;
        }
    }
    if (self.payFinishedBlock) {
        self.payFinishedBlock(paySuccess,resultStatus,strMemo);
    }
    self.payFinishedBlock=nil;
}


@end
